//package com.demo.controller;
//
//import com.alibaba.excel.EasyExcel;
//import com.alibaba.excel.ExcelWriter;
//import com.alibaba.excel.metadata.Font;
//import com.alibaba.excel.metadata.Sheet;
//import com.alibaba.excel.metadata.Table;
//import com.alibaba.excel.metadata.TableStyle;
//import com.alibaba.excel.support.ExcelTypeEnum;
//import com.alibaba.excel.write.metadata.style.WriteCellStyle;
//import com.alibaba.excel.write.metadata.style.WriteFont;
//import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
//import com.demo.entity.User;
//import com.demo.entity.UserExportExcelVo;
//import com.demo.handler.ContentHandler;
//import com.demo.utils.EasyExcelUtil;
//import com.demo.handler.TitleHandler;
//import org.apache.poi.ss.usermodel.IndexedColors;
//import org.junit.Test;
//import org.springframework.web.bind.annotation.GetMapping;
//import org.springframework.web.bind.annotation.RequestMapping;
//import org.springframework.web.bind.annotation.RestController;
//
//import javax.servlet.http.HttpServletResponse;
//import java.io.FileNotFoundException;
//import java.io.FileOutputStream;
//import java.io.IOException;
//import java.io.OutputStream;
//import java.net.URLEncoder;
//import java.text.SimpleDateFormat;
//import java.time.LocalDateTime;
//import java.time.format.DateTimeFormatter;
//import java.util.ArrayList;
//import java.util.Arrays;
//import java.util.Date;
//import java.util.HashMap;
//import java.util.List;
//
//@RestController
//@RequestMapping
//public class TestController {
//
//    private final String FILE_PATH = "D:\\测试.xlsx";
//    private String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
//
//
//
//    @GetMapping("/exportExcel")
//    public void exportExcel(HttpServletResponse response) throws IOException {
//        // 非自动列宽
//        // EasyExcel.write(response.getOutputStream(), BankLoanExportExcel.class).sheet("放款情况").doWrite(listExcel);
//        // 自动列宽
//        // EasyExcel.write(response.getOutputStream(), BankLoanExportExcel.class) .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).sheet("放款情况").doWrite(listExcel);
//
//        /*******自定义列标题和内容的样式******/
//        // 头的策略
//        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
//        // 背景设置为红色
//        headWriteCellStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
//        WriteFont headWriteFont = new WriteFont();
//        headWriteFont.setFontHeightInPoints((short)10);
//        headWriteCellStyle.setWriteFont(headWriteFont);
//        // 内容的策略
//        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
//        // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
////          contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
//        // 背景绿色
////          contentWriteCellStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
//        WriteFont contentWriteFont = new WriteFont();
//        // 字体大小
//        contentWriteFont.setFontHeightInPoints((short)10);
//        contentWriteCellStyle.setWriteFont(contentWriteFont);
//
//        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
//        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
//            new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
//        response.setContentType("application/vnd.ms-excel");
//        response.setCharacterEncoding("utf-8");
//        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
//        String fileName = URLEncoder.encode("测试", "UTF-8");
//        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
//        // 注删样式并写入excel
//        EasyExcel.write(response.getOutputStream(), UserExportExcelVo.class).registerWriteHandler(horizontalCellStyleStrategy).sheet("导出模板").doWrite(createModelList());
//    }
//
//    /**
//     * 导出本地
//     * @throws FileNotFoundException
//     */
//    @GetMapping("/testExportToLocal")
//    public String testExportToLocal() throws FileNotFoundException {
//        // 输出流
//        OutputStream outputStream = new FileOutputStream(FILE_PATH);
//        // 指定标红色的列
//        List<Integer> columns = Arrays.asList(0, 1);
//        // 指定批注
//        HashMap<Integer, String> annotationsMap = new HashMap<>();
//        annotationsMap.put(0,"第一列标题批注");
//        annotationsMap.put(1,"第二列标题批注");
//        TitleHandler titleHandler = new TitleHandler(columns, IndexedColors.RED.getIndex(),annotationsMap);
//        EasyExcelUtil.writeExcelWithModel(outputStream, createModelList(), UserExportExcelVo.class, "测试", titleHandler, new ContentHandler());
//        return "success";
//    }
//
//    /**
//     * 导出浏览器
//     * @param response
//     * @throws FileNotFoundException
//     */
//    @GetMapping("/testExportToWeb")
//    public void testExportToWeb(HttpServletResponse response) throws IOException {
//        // 指定标红色的列
//        List<Integer> columns = Arrays.asList(0, 1);
//        // 指定批注
//        HashMap<Integer, String> annotationsMap = new HashMap<>();
//        annotationsMap.put(0,"第一列标题批注");
//        annotationsMap.put(1,"第二列标题批注");
//        TitleHandler titleHandler = new TitleHandler(columns, IndexedColors.RED.getIndex(),annotationsMap);
//        response.setContentType("application/vnd.ms-excel");
//        response.setCharacterEncoding("utf-8");
//        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
//        String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");
//        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
//        EasyExcelUtil.writeExcelWithModel(response.getOutputStream(), createModelList(), UserExportExcelVo.class, "测试", titleHandler);
//    }
//
//
//    @GetMapping("/download")
//    public void download(HttpServletResponse response) throws IOException {
//        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
//        response.setContentType("application/vnd.ms-excel");
//        response.setCharacterEncoding("utf-8");
//        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
//        String fileName = URLEncoder.encode("测试", "UTF-8");
//        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
//        List<UserExportExcelVo> list = createModelList();
//        EasyExcel.write(response.getOutputStream(), User.class).sheet("模板").doWrite(list);
//    }
//
////    @RequestMapping("/exportExcel")
////    public void export(HttpServletResponse response) throws IOException {
////        List<UserExportExcelVo> list = createModelList();
////        ServletOutputStream out = response.getOutputStream();
////        ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX, true);
////        String fileName = "测试exportExcel";
////        Sheet sheet = new Sheet(1, 0,UserExportExcelVo.class);
////        //设置自适应宽度
////        sheet.setAutoWidth(Boolean.TRUE);
////        // 第一个 sheet 名称
////        sheet.setSheetName("第一个sheet");
////        writer.write(list, sheet);
////        //通知浏览器以附件的形式下载处理，设置返回头要注意文件名有中文
////        response.setHeader("Content-disposition", "attachment;filename=" + new String( fileName.getBytes("gb2312"), "ISO8859-1" ) + ".xlsx");
////        writer.finish();
////        response.setContentType("multipart/form-data");
////        response.setCharacterEncoding("utf-8");
////        out.flush();
////    }
//
////    /**
////     * 测试环境
////     */
////
////    /**
////     * 注解方式生成 Excel
////     * @throws IOException
////     */
////    @Test
////    public void writeExcelAnnotation() throws IOException {
////        // 生成EXCEL并指定输出路径
////        OutputStream out = new FileOutputStream(FILE_PATH);
////        ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
////        // 设置SHEET
////        Sheet sheet = new Sheet(1, 0, UserExportExcelVo.class);
////        sheet.setSheetName("sheet1");
////        writer.write(createModelList(),sheet);
////        writer.finish();
////        out.close();
////    }
//
//    private List<UserExportExcelVo> createModelList(){
//        List<UserExportExcelVo> userList = new ArrayList<>();
//        for (int i = 1; i <= 100; i++){
//            UserExportExcelVo userExportExcelVo = new UserExportExcelVo();
//            userExportExcelVo.setUid(i);
//            userExportExcelVo.setName("wang" + i);
//            userExportExcelVo.setAge(i);
//            userExportExcelVo.setBirthday(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
//            userList.add(userExportExcelVo);
//        }
//        return userList;
//    }
//
//    /**
//     * 动态生成 Excel
//     */
//    @Test
//    public void writeExcelDynamic() throws IOException {
//        // 生成EXCEL并指定输出路径
//        OutputStream out = new FileOutputStream(FILE_PATH);
//        ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
//        // 设置SHEET
//        Sheet sheet = new Sheet(1, 0);
//        sheet.setSheetName("sheet1");
//        Table table = new Table(1);
//        table.setHead(headList());
//        // 设置表格样式
////        table.setTableStyle(createTableStyle());
//        writer.write1(createDynamicModelList(), sheet, table);
//        writer.merge(0, 0, 1, 2);
//        writer.merge(0, 0, 3, 4);
//        writer.finish();
//        out.close();
//    }
//
//    /**
//     * 表头数据
//     * @return
//     */
//    private List<List<String>> headList(){
//        List<List<String>> headList = new ArrayList<>();
//        List<String> column1 = new ArrayList<>();
//        List<String> column2 = new ArrayList<>();
//        List<String> column3 = new ArrayList<>();
//        List<String> column4 = new ArrayList<>();
//        column1.add("第一列");
//        column2.add("第二列");
//        column3.add("第三列");
//        column4.add("第四列");
//        headList.add(column1);
//        headList.add(column2);
//        headList.add(column3);
//        headList.add(column4);
//        return headList;
//    }
//
//    /**
//     * 所有行数据
//     * @return
//     */
//    private List<List<Object>> createDynamicModelList(){
//        // 所有行数据
//        List<List<Object>> rows = new ArrayList<>();
//        for (int i = 1; i <= 100; i++){
//            // 一行数据
//            List<Object> row = new ArrayList<>();
//            row.add(i);
//            row.add("wang" + i);
//            row.add(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
//            row.add("我就随便写点东西用来测试这个单元格是否能够自适应大小，如果不能自适应是什么效果？能自适应又是什么效果？");
//            rows.add(row);
//        }
//        return rows;
//    }
//
//    /**
//     * 设置自定义表格样式的代码
//     */
//    public TableStyle createTableStyle(){
//        TableStyle tableStyle = new TableStyle();
//        // 设置表头样式
//        Font headFont = new Font();
//        // 字体是否加粗
//        headFont.setBold(true);
//        // 字体大小
//        headFont.setFontHeightInPoints((short) 14);
//        // 字体
////        headFont.setFontName("楷体");
//        tableStyle.setTableHeadFont(headFont);
//        // 背景色
//        tableStyle.setTableHeadBackGroundColor(IndexedColors.GREY_25_PERCENT);
//        // 设置表格样式
//        Font contentFont = new Font();
////        contentFont.setBold(true);
//        contentFont.setFontHeightInPoints((short) 12);
////        contentFont.setFontName("黑体");
//        tableStyle.setTableContentFont(contentFont);
//        tableStyle.setTableContentBackGroundColor(IndexedColors.WHITE);
//        return tableStyle;
//    }
//
//    /**
//     * 针对较少的记录数(20W以内大概)可以调用该方法一次性查出然后写入到EXCEL的一个SHEET中
//     * 注意： 一次性查询出来的记录数量不宜过大，不会内存溢出即可。
//     *
//     */
//    @Test
//    public void writeExcelOneSheetOnceWrite() throws IOException {
//
//
//        // 生成EXCEL并指定输出路径
//        OutputStream out = new FileOutputStream(FILE_PATH);
//        ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
//        // 设置SHEET
//        Sheet sheet = new Sheet(1, 0);
//        sheet.setSheetName("sheet1");
//        // 设置标题
//        Table table = new Table(1);
//        List<List<String>> titles = new ArrayList<List<String>>();
//        titles.add(Arrays.asList("用户ID"));
//        titles.add(Arrays.asList("名称"));
//        titles.add(Arrays.asList("年龄"));
//        titles.add(Arrays.asList("生日"));
//        table.setHead(titles);
//        // 查询数据导出即可 比如说一次性总共查询出100条数据
//        List<List<String>> userList = new ArrayList<>();
//        for (int i = 0; i < 100; i++) {
//            userList.add(Arrays.asList("ID_" + i, "小明" + i, String.valueOf(i), date));
//        }
//        writer.write0(userList, sheet, table);
//        writer.finish();
//    }
//
//    /**
//     * 针对105W以内的记录数可以调用该方法分多批次查出然后写入到EXCEL的一个SHEET中
//     * 注意：
//     * 每次查询出来的记录数量不宜过大，根据内存大小设置合理的每次查询记录数，不会内存溢出即可。
//     * 数据量不能超过一个SHEET存储的最大数据量105W
//     *
//     * @throws IOException
//     */
//    @Test
//    public void writeExcelOneSheetMoreWrite() throws IOException {
//
//        // 生成EXCEL并指定输出路径
//        OutputStream out = new FileOutputStream(FILE_PATH);
//        ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
//
//        // 设置SHEET
//        Sheet sheet = new Sheet(1, 0);
//        sheet.setSheetName("sheet1");
//
//        // 设置标题
//        Table table = new Table(1);
//        List<List<String>> titles = new ArrayList<List<String>>();
//        titles.add(Arrays.asList("用户ID"));
//        titles.add(Arrays.asList("名称"));
//        titles.add(Arrays.asList("年龄"));
//        titles.add(Arrays.asList("生日"));
//        table.setHead(titles);
//        // 模拟分批查询：总记录数50条，每次查询20条，分三次查询 最后一次查询记录数是10
//        Integer totalRowCount = 50;
//        Integer pageSize = 20;
//        Integer writeCount = totalRowCount % pageSize == 0 ? (totalRowCount / pageSize) : (totalRowCount / pageSize + 1);
//        // 注： 此处仅仅为了模拟数据，实用环境不需要将最后一次分开，合成一个即可， 参数为： currentPage = i+1;  pageSize = pageSize
//        for (int i = 0; i < writeCount; i++) {
//            // 前两次查询 每次查20条数据
//            if (i < writeCount - 1) {
//                List<List<String>> userList = new ArrayList<>();
//                for (int j = 0; j < pageSize; j++) {
//                    userList.add(Arrays.asList("ID_" + Math.random(), "小明", String.valueOf(Math.random()), date));
//                }
//                writer.write0(userList, sheet, table);
//            } else if (i == writeCount - 1) {
//                // 最后一次查询 查多余的10条记录
//                List<List<String>> userList = new ArrayList<>();
//                Integer lastWriteRowCount = totalRowCount - (writeCount - 1) * pageSize;
//                for (int j = 0; j < lastWriteRowCount; j++) {
//                    userList.add(Arrays.asList("ID_" + Math.random(), "小明", String.valueOf(Math.random()), date));
//                }
//                writer.write0(userList, sheet, table);
//            }
//        }
//        writer.finish();
//    }
//
//    /**
//     * 针对几百万的记录数可以调用该方法分多批次查出然后写入到EXCEL的多个SHEET中
//     * 注意：
//     * perSheetRowCount % pageSize要能整除  为了简洁，非整除这块不做处理
//     * 每次查询出来的记录数量不宜过大，根据内存大小设置合理的每次查询记录数，不会内存溢出即可。
//     *
//     * @throws IOException
//     */
//    @Test
//    public void writeExcelMoreSheetMoreWrite() throws IOException {
//
//        // 生成EXCEL并指定输出路径
//        OutputStream out = new FileOutputStream(FILE_PATH);
//        ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
//        // 设置SHEET名称
//        String sheetName = "测试SHEET";
//        // 设置标题
//        Table table = new Table(1);
//        List<List<String>> titles = new ArrayList<List<String>>();
//        titles.add(Arrays.asList("用户ID"));
//        titles.add(Arrays.asList("名称"));
//        titles.add(Arrays.asList("年龄"));
//        titles.add(Arrays.asList("生日"));
//        table.setHead(titles);
//        // 模拟分批查询：总记录数250条，每个SHEET存100条，每次查询20条  则生成3个SHEET，前俩个SHEET查询次数为5，最后一个SHEET查询次数为3 最后一次写的记录数是10
//        // 注：该版本为了较少数据判断的复杂度，暂时perSheetRowCount要能够整除pageSize， 不去做过多处理  合理分配查询数据量大小不会内存溢出即可。
//        Integer totalRowCount = 250;
//        Integer perSheetRowCount = 100;
//        Integer pageSize = 20;
//        Integer sheetCount = totalRowCount % perSheetRowCount == 0 ? (totalRowCount / perSheetRowCount) : (totalRowCount / perSheetRowCount + 1);
//        Integer previousSheetWriteCount = perSheetRowCount / pageSize;
//        Integer lastSheetWriteCount = totalRowCount % perSheetRowCount == 0 ?
//                previousSheetWriteCount :
//                (totalRowCount % perSheetRowCount % pageSize == 0 ? totalRowCount % perSheetRowCount / pageSize : (totalRowCount % perSheetRowCount / pageSize + 1));
//        for (int i = 0; i < sheetCount; i++) {
//            // 创建SHEET
//            Sheet sheet = new Sheet(i, 0);
//            sheet.setSheetName(sheetName + i);
//            if (i < sheetCount - 1) {
//                // 前2个SHEET, 每个SHEET查5次 每次查20条 每个SHEET写满100行  2个SHEET合计200行  实用环境：参数： currentPage: j+1 + previousSheetWriteCount*i, pageSize: pageSize
//                for (int j = 0; j < previousSheetWriteCount; j++) {
//                    List<List<String>> userList = new ArrayList<>();
//                    for (int k = 0; k < 20; k++) {
//                        userList.add(Arrays.asList("ID_" + Math.random(), "小明", String.valueOf(Math.random()), date));
//                    }
//                    writer.write0(userList, sheet, table);
//                }
//            } else if (i == sheetCount - 1) {
//                // 最后一个SHEET 实用环境不需要将最后一次分开，合成一个即可， 参数为： currentPage = i+1;  pageSize = pageSize
//                for (int j = 0; j < lastSheetWriteCount; j++) {
//                    // 前俩次查询 每次查询20条
//                    if (j < lastSheetWriteCount - 1) {
//                        List<List<String>> userList = new ArrayList<>();
//                        for (int k = 0; k < 20; k++) {
//                            userList.add(Arrays.asList("ID_" + Math.random(), "小明", String.valueOf(Math.random()), date));
//                        }
//                        writer.write0(userList, sheet, table);
//                    } else if (j == lastSheetWriteCount - 1) {
//                        // 最后一次查询 将剩余的10条查询出来
//                        List<List<String>> userList = new ArrayList<>();
//                        Integer lastWriteRowCount = totalRowCount - (sheetCount - 1) * perSheetRowCount - (lastSheetWriteCount - 1) * pageSize;
//                        for (int k = 0; k < lastWriteRowCount; k++) {
//                            userList.add(Arrays.asList("ID_" + Math.random(), "小明1", String.valueOf(Math.random()), date));
//                        }
//                        writer.write0(userList, sheet, table);
//                    }
//                }
//            }
//        }
//        writer.finish();
//    }
//
//
//
//
//
//}
